#include <stdio.h>
#include <unistd.h>
#include <limits.h>
#include <stdlib.h>
#include <fcntl.h>
#include <time.h>
#include <math.h>
#include <gmp.h> // Tag -lgmp antes de compilar

#define KICKS  ULONG_MAX
#define BASE 10
#define MANTISSA 1024*1024*32  // quanto maior pior o tempo

/*

Em um core de 1.8Ghz e Mantissa de 2Kb:
Para um milhao de Kicks demora ~23sec
Para cem milhoes demora 2408sec (~40min).
-- Então o algoritimo e O(n).

Devido a natureza estatistica,
Para 100M de Kicks são 4 casa decimais corretas.

#define KICKS ULONG_MAX // 42.294.967.295 = 32bits
--- Isto demoraria ~27 horas.

Para 64bits seriam 13.453anos :o)

*/

int get_random(){
		int fd, nrandom;
		fd = open("/dev/random", O_RDONLY);
		read(fd, &nrandom, sizeof(nrandom));
		close(fd);
		return nrandom;
}

int main(int argc, char *argv[]){
		
		unsigned long int i, hits=0;
		time_t t_zero, t_final;
		double delta_t;
        double X, Y, R;
		int cmp;

		// Marca o tmepo 
		time(&t_zero);

		// Configura seed das funcoes Random
        srand(get_random());	
	
		// Float com precisao arbitratia
		mpf_set_default_prec(MANTISSA);
		mpf_t pi;
	
		for(i=0; i<KICKS; i++){

			// Distribuicao uniforme 0<x<1;
            X = (double) rand()/ (double) RAND_MAX;
            Y = (double) rand()/ (double) RAND_MAX;		    

			// Pitagoras
            R = (X*X)+(Y*Y);
            R = sqrt(R); 
			//Avaliacao
			if(R<=1) hits++;
		
		}
			
        mpf_init(pi);
        mpf_set_ui(pi, hits);
        mpf_div_ui(pi, pi, KICKS);  
        mpf_mul_ui(pi, pi, 4);  
 
		mpf_out_str(NULL, BASE, 0, pi);
		
		// Limpa a Caquinha
		mpf_clear(pi);

		time(&t_final);	
		delta_t  = difftime(t_final, t_zero);

		printf("\nTempo = %.2lf segundos\n", delta_t);
		
	return 0;

}
